# Copyright (c) 2021-2023 Alibaba Cloud Computing Ltd.
# SPDX-License-Identifier: MulanPSL-2.0

import json
import logging

from tornado.web import RequestHandler
from collections import defaultdict

from agent.controller import get_feature_handler, get_domain_handler

logger = logging.getLogger('common')

class BackupHandler(RequestHandler):
    def post(self):
        request_data = json.loads(self.request.body)
        logger.debug("Backup request data: {}".format(request_data))

        backup_result = defaultdict(dict)
        for domain_name, param_list in request_data.items():
            backup_result[domain_name]['param_result'] = {}
            
            handled_feature = []
            for param_name in param_list.keys():
                try:
                    feature_handler = get_feature_handler(domain_name, param_name)
                    try:
                        # Add param to handled list even if backup failed in feature-level handler
                        # There is no need to try again in domain-level handler
                        logger.info("backup in feature-level hander '{}:{}'".format(domain_name, param_name))
                        handled_feature.append(param_name)
                        feature_handler.backup()
                        backup_result[domain_name]['param_result'][param_name] = {"suc": True, "msg": ""}
                        
                    except Exception as e:
                        # Failed to backup in feature-level handler
                        logger.error("backup failed in feature-level handler: {}".format(e))
                        backup_result[domain_name]['param_result'][param_name] = {"suc": False, "msg": "{}".format(e)}
                        
                except Exception:
                    # can not find feature-level handler, try in domain-level handler
                    continue
            
            # Remove handled feature in 'param_list'
            for f in handled_feature:
                param_list.pop(f)
            
            # All param handled in feature-level handler
            if param_list.__len__() == 0:
                continue

            # Try to find domain-level handler
            try:
                domain_handler = get_domain_handler(domain_name)
                try:
                    logger.info("backup in domain-level hander '{}'".format(domain_name))
                    # Merge domain-level handler result
                    for param_name, backup_res in domain_handler.backup(param_list).items():
                        backup_result[domain_name]['param_result'][param_name] = backup_res
                    
                    backup_result[domain_name]['suc'] = True
                    backup_result[domain_name]['msg'] = ""
                    
                except Exception as e:
                    # Backup failed in domain-level handler
                    logger.error("backup failed in domain-level handler: {}".format(e))
                    backup_result[domain_name]['suc'] = False
                    backup_result[domain_name]['msg'] = "{}".format(e)
                    
            # Can not find bother feature-level and domain-level handler
            except Exception as e:
                backup_result[domain_name]['suc'] = False
                backup_result[domain_name]['msg'] = "no acceptable handler of '{}': {}".format(domain_name, e)
            
        logger.debug("Backup response data: {}".format(backup_result))
        self.write(json.dumps(backup_result))
        self.finish()